#include "StdAfx.h"
#include <cassert>
#include <new>
#include "IOCPUDPSrv.h"
#include "../../public/fclib/FCThreadHelper.h"

using namespace std;
using namespace fclib::fcthread;

#pragma warning(push)
#pragma warning(disable:4996)

namespace {
    INT32 const DATA_LEFT_FLAG = -1;
    INT32 const IOCP_HEAD_LEN = 8;
    ULONG_PTR const IOCP_QUIT_FLAG = 0xCCCCCCCC;
}

#define FC_STRNCPY(dst, src) ::strncpy((dst), (src), _countof(dst))
#define FC_ERROR(fmt, ...) TRACE("error: %s:"fmt"\n", __FUNCTION__, ##__VA_ARGS__)
#define FC_INFO(fmt, ...) TRACE("info: %s:"fmt"\n", __FUNCTION__, ##__VA_ARGS__)
#define FC_WARN(fmt, ...) TRACE("warn: %s:"fmt"\n", __FUNCTION__, ##__VA_ARGS__)

#define GOTO_BLOCK_BEGIN
#define GOTO_BLOCK_END \
    exit_label:
#define GOTO_BLOCK_EXIT goto exit_label

/*---------------------------struct t_PER_IO_DATA----------------------------*/
void CIOCPUDPSrv::t_PER_IO_DATA::init(e_PerIOOpType opType, bool bAutoReDo/* = false*/)
{
    ZeroMemory(&overlapped, sizeof(overlapped));
    ZeroMemory(buffer, sizeof(buffer));
    bufferOffset = 0;
    ZeroMemory(&addr, sizeof(addr));
    addrlen = sizeof(addr);
    operationType = opType;
    bAutoReRecv = bAutoReDo;
}

/*---------------------------struct t_PER_HANDLE_DATA----------------------------*/
bool CIOCPUDPSrv::t_PER_HANDLE_DATA::IsShouldBeClosed(time_t tNow, int iIntervalSeconds)
{
    return (state & (SS_CONNECTED | SS_ACCEPTED)) 
        && (difftime(tNow, tActiveTime) > iIntervalSeconds || nUsed > UDP_MAX_PENDING_OPERATION);
}
bool CIOCPUDPSrv::t_PER_HANDLE_DATA::CanDestroy(void)
{
    return (SS_CLOSED == state) && (0 == nUsed);
}
void CIOCPUDPSrv::t_PER_HANDLE_DATA::Init(void)
{
    s = INVALID_SOCKET;
    ZeroMemory(&addr, sizeof(addr));
    nUsed = 0;
    dataSize = DATA_LEFT_FLAG;
    state = SS_INVALID;
    tActiveTime = time(NULL);
}


#pragma warning(pop)
